Skip to content

Conversation

mjkeaton
Copy link
Contributor

@mjkeaton mjkeaton commented Feb 24, 2025

User description

  • Generates an API client from the Wildcat OpenAPI definition
  • Uses client to fetch pending quotes
  • Lookup quotes by id
  • Add dev mode switch on settings page
  • Mock balances

PR Type

Enhancement, Tests, Dependencies, Configuration changes, Documentation


Description

  • Generated an API client from the Wildcat OpenAPI definition, including TypeScript types, React Query hooks, and SDK functions for API interactions.

  • Enhanced the balances and quotes pages with new components, charts, and developer mode features.

  • Added new pages and routing for displaying individual quote details.

  • Introduced mock handlers, mock database entries, and updated test configurations for API interactions.

  • Updated dependencies, scripts, and configurations for OpenAPI client generation and integration.

  • Added new utility functions and hooks for local storage and API client management.

  • Improved UI components such as breadcrumbs, sidebar, and labels for better user experience.

  • Added and updated OpenAPI specification files for development and minimal API definitions.


Changes walkthrough 📝

Relevant files
Enhancement
10 files
BalancesPage.tsx
Enhanced balances page with charts and developer mode.     

src/pages/balances/BalancesPage.tsx

  • Added new components for displaying Bitcoin and other balance charts
    using recharts.
  • Introduced a Loader component for suspense fallback.
  • Implemented PageBody and DevSection for rendering balance data and
    developer mode details.
  • Replaced the previous BalanceChart with new card-based balance
    displays.
  • +201/-4 
    QuotePage.tsx
    New QuotePage for displaying quote details.                           

    src/pages/quotes/QuotePage.tsx

  • Added a new page for displaying individual quote details.
  • Included Loader, Quote, and DevSection components for rendering quote
    data and developer mode.
  • Utilized useSuspenseQuery for fetching quote data.
  • +114/-0 
    api.ts
    Refactored API utilities for balance fetching.                     

    src/lib/api.ts

  • Refactored API utility to fetch balances instead of quotes.
  • Removed unused quote-related API functions.
  • Updated apiFetch utility for improved error handling.
  • +46/-42 
    QuotesPage.tsx
    Enhanced QuotesPage with React Query and navigation.         

    src/pages/quotes/QuotesPage.tsx

  • Updated the quotes page to use React Query for fetching pending
    quotes.
  • Added navigation and linking for individual quote pages.
  • Introduced a developer mode section for raw quote data.
  • +23/-8   
    SettingsPage.tsx
    Added developer mode toggle to settings page.                       

    src/pages/settings/SettingsPage.tsx

  • Introduced a developer mode toggle using local storage.
  • Added a Loader component for suspense fallback.
  • Updated the settings page layout with new components.
  • +39/-0   
    Breadcrumbs.tsx
    Enhanced breadcrumbs with parent link support.                     

    src/components/Breadcrumbs.tsx

  • Enhanced breadcrumbs to support parent links.
  • Updated the component structure for better navigation.
  • +15/-1   
    use-local-storage.ts
    New custom hook for local storage management.                       

    src/hooks/use-local-storage.ts

  • Added a custom hook for managing local storage state.
  • Included utility functions for setting, getting, and removing items.
  • +31/-0   
    local-storage.ts
    Utility functions for local storage operations.                   

    src/utils/local-storage.ts

  • Added utility functions for interacting with local storage.
  • Included methods for setting, getting, and removing items.
  • +24/-0   
    label.tsx
    New Label component using Radix UI.                                           

    src/components/ui/label.tsx

  • Added a new Label component using Radix UI.
  • Styled the component for consistent usage across the app.
  • +22/-0   
    use-api-client.ts
    New hook for accessing API client.                                             

    src/hooks/use-api-client.ts

  • Added a custom hook for accessing the generated API client.
  • Simplified API client usage across the application.
  • +5/-0     
    Dependencies
    8 files
    types.gen.ts
    Auto-generated API client types for quotes and balances. 

    src/generated/client/types.gen.ts

  • Added auto-generated TypeScript types for API responses and requests.
  • Defined types for quotes, balances, and various API interactions.
  • Included detailed schemas for handling quote statuses and actions.
  • +330/-0 
    react-query.gen.ts
    Auto-generated React Query hooks for API client.                 

    src/generated/client/@tanstack/react-query.gen.ts

  • Added auto-generated React Query hooks for API interactions.
  • Included query and mutation options for managing quotes and balances.
  • Provided utility functions for creating query keys.
  • +198/-0 
    sdk.gen.ts
    Auto-generated SDK for API interactions.                                 

    src/generated/client/sdk.gen.ts

  • Added auto-generated SDK functions for interacting with the API.
  • Included methods for fetching and resolving quotes.
  • Provided utility functions for managing API requests.
  • +86/-0   
    client.gen.ts
    Auto-generated client configuration for API.                         

    src/generated/client/client.gen.ts

  • Added auto-generated client configuration for API interactions.
  • Included utility for creating client instances.
  • +16/-0   
    index.ts
    Auto-generated index for API client exports.                         

    src/generated/client/index.ts

  • Added an auto-generated index file for API client exports.
  • Consolidated exports for easier imports in the application.
  • +3/-0     
    mockServiceWorker.js
    Updated mock service worker version.                                         

    public/mockServiceWorker.js

  • Updated the mock service worker package version.
  • Ensured compatibility with the latest mock service worker features.
  • +1/-1     
    package.json
    Updated dependencies and scripts for OpenAPI integration.

    package.json

  • Added new dependencies for OpenAPI client generation and Radix UI.
  • Updated existing dependencies to their latest versions.
  • Added a new script for running OpenAPI client generation.
  • +21/-17 
    package-lock.json
    Dependency updates and additions for API client integration.

    package-lock.json

  • Added new dependencies such as @hey-api/client-fetch and
    @hey-api/openapi-ts.
  • Updated several existing dependencies to newer versions, including
    @tailwindcss/vite, @tanstack/react-query, and eslint.
  • Removed unused dependencies like @pkgr/core and
    eslint-plugin-prettier.
  • Introduced new dev dependencies such as chokidar, dotenv, and
    handlebars.
  • +664/-188
    Tests
    4 files
    db.ts
    Extended mock database with quote entries.                             

    src/mocks/db.ts

  • Added mock database entries for quotes with various statuses.
  • Extended the mock database schema to include quote-related fields.
  • +56/-0   
    admin_quotes.ts
    Added mock handlers for admin quote APIs.                               

    src/mocks/handlers/admin_quotes.ts

  • Added a new handler for fetching individual quote details.
  • Updated the pending quotes handler to fetch data from the mock
    database.
  • +25/-14 
    balances.ts
    Added mock handler for balance API.                                           

    src/mocks/handlers/balances.ts

  • Added a mock handler for fetching balance data.
  • Simulated API response with mock balance values.
  • +27/-0   
    handlers.ts
    Updated mock handlers for API endpoints.                                 

    src/mocks/handlers.ts

  • Added new handlers for fetching balances and individual quotes.
  • Updated the handlers list to include the new mock handlers.
  • +3/-2     
    Configuration changes
    6 files
    main.tsx
    Added routing for QuotePage.                                                         

    src/main.tsx

  • Added a new route for the QuotePage.
  • Updated the main application routing structure.
  • +2/-0     
    openapi-ts.config.ts
    Configuration for OpenAPI client generation.                         

    openapi-ts.config.ts

  • Added configuration for generating API client using OpenAPI.
  • Defined input and output paths for the generated files.
  • +19/-0   
    eslint.config.js
    Updated ESLint configuration to exclude generated files. 

    eslint.config.js

  • Excluded the src/generated directory from ESLint checks.
  • Prevented linting of auto-generated files.
  • +1/-0     
    tsconfig.app.json
    Updated TypeScript configuration for OpenAPI integration.

    tsconfig.app.json

  • Included openapi-ts.config.ts in the TypeScript configuration.
  • Updated the include paths for better coverage.
  • +2/-1     
    .env.development
    Updated development environment variables.                             

    .env.development

  • Cleared the VITE_API_BASE_URL value for development.
  • Adjusted environment variables for API mocking.
  • +1/-1     
    .prettierignore
    Updated Prettier ignore configuration.                                     

    .prettierignore

  • Excluded the src/generated directory from Prettier formatting.
  • Prevented formatting of auto-generated files.
  • +1/-0     
    Formatting
    2 files
    layout.tsx
    Minor UI improvement for sidebar trigger.                               

    src/layout.tsx

  • Added a cursor pointer style to the sidebar trigger.
  • Minor UI improvement for better user interaction.
  • +1/-1     
    AppSidebar.tsx
    Updated sidebar item title for clarity.                                   

    src/components/AppSidebar.tsx

  • Corrected the title of the "Balances" sidebar item.
  • Improved clarity and consistency in the sidebar navigation.
  • +1/-1     
    Documentation
    2 files
    __dev_openapi.json
    Added development OpenAPI specification.                                 

    opt/wildcat/__dev_openapi.json

  • Added a development OpenAPI specification file.
  • Defined API paths, schemas, and components for the Wildcat API.
  • +752/-0 
    openapi.json
    Added minimal OpenAPI specification.                                         

    opt/wildcat/openapi.json

  • Added a minimal OpenAPI specification file for the Wildcat API.
  • Included basic API paths and schemas.
  • +1/-0     
    Additional files
    2 files
    BalanceChart.tsx +0/-44   
    api.ts +0/-26   

    Need help?
  • Type /help how to ... in the comments thread for any questions about Qodo Merge usage.
  • Check out the documentation for more information.
  •  @eslint/js                    ^9.19.0  →   ^9.21.0
     @tailwindcss/vite              ^4.0.7  →    ^4.0.8
     @tanstack/react-query         ^5.66.8  →   ^5.66.9
     @types/node                  ^22.13.4  →  ^22.13.5
     @types/react                  ^19.0.8  →  ^19.0.10
     @types/react-dom              ^19.0.3  →   ^19.0.4
     eslint                        ^9.20.1  →   ^9.21.0
     eslint-plugin-react-hooks      ^5.0.0  →    ^5.1.0
     eslint-plugin-react-refresh   ^0.4.18  →   ^0.4.19
     msw                            ^2.7.0  →    ^2.7.1
     prettier                       ^3.5.1  →    ^3.5.2
     tailwind-merge                 ^3.0.1  →    ^3.0.2
     tailwindcss                    ^4.0.7  →    ^4.0.8
     typescript                     ~5.7.2  →    ~5.7.3
     typescript-eslint             ^8.22.0  →   ^8.24.1
     vite                           ^6.1.0  →    ^6.1.1
    @mjkeaton mjkeaton self-assigned this Feb 24, 2025
    @mjkeaton mjkeaton changed the title prepare quote views and actions ui: prepare quote views and actions Feb 24, 2025
    @mjkeaton mjkeaton changed the title ui: prepare quote views and actions ui: prepare quote list and actions Feb 24, 2025
    @mjkeaton mjkeaton changed the title ui: prepare quote list and actions ui: prepare api client and display pending quotes Feb 24, 2025
    @mjkeaton mjkeaton marked this pull request as ready for review February 24, 2025 18:00
    @mjkeaton mjkeaton requested a review from mtbitcr February 24, 2025 18:00
    @mjkeaton mjkeaton added the enhancement New feature or request label Feb 24, 2025
    Copy link

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 No relevant tests
    🔒 Security concerns

    API Security:
    The apiFetch utility in src/lib/api.ts has commented out Content-Type headers and accepts empty headers array, which could allow malicious content types or missing security headers in API requests. Additionally, sensitive data like balances and quotes are stored in localStorage without encryption or sanitization.

    ⚡ Recommended focus areas for review

    Security Risk

    The apiFetch function has commented out Content-Type header and accepts empty headers array, which could lead to security issues when making API requests

    const response = await fetch(url, {
      ...options,
      /* headers: {
        "Content-Type": "application/json",
        ...(options.headers || {}),
      }, */
      headers: options.headers ?? [],
    })
    Error Handling

    The hook silently catches and logs errors without proper error handling or user notification when localStorage operations fail

    import { getItem, setItem, removeItem } from "@/utils/local-storage"
    
    type DispatchAction<T> = T | ((prevState: T) => T)
    
    export default function useLocalStorage<T>(key: string, initialValue: T) {
      const [value, setValue] = useState(() => {
        const data = getItem(key)
        return (data || initialValue) as T
      })
    
      function handleDispatch(action: DispatchAction<T>) {
        if (typeof action === "function") {
          setValue((prevState) => {
            const newValue = (action as (prevState: T) => T)(prevState)
            setItem(key, newValue)
            return newValue
          })
        } else {
          setValue(action)
          setItem(key, action)
        }
      }
    
      function clearState() {
        setValue(undefined as T)
        removeItem(key)
      }
    
      return [value, handleDispatch, clearState] as const
    }
    Performance

    Multiple heavy chart components with static data are rendered without memoization or performance optimizations

    export function BitcoinBalanceChart() {
      const config = {
        bitcoin: {
          label: "Bitcoin",
          color: "#2563eb",
        },
      } satisfies ChartConfig
    
      const data = [
        { month: "January", bitcoin: 186 },
        { month: "February", bitcoin: 305 },
        { month: "March", bitcoin: 237 },
        { month: "April", bitcoin: 73 },
        { month: "May", bitcoin: 209 },
        { month: "June", bitcoin: 214 },
        { month: "July", bitcoin: 21 },
        { month: "August", bitcoin: 32 },
        { month: "September", bitcoin: 0 },
        { month: "October", bitcoin: 0 },
        { month: "November", bitcoin: 0 },
        { month: "December", bitcoin: 0 },
      ]
    
      return (
        <ChartContainer config={config} className="min-h-[200px] w-full">
          <BarChart accessibilityLayer data={data}>
            <CartesianGrid vertical={false} />
            <XAxis
              dataKey="month"
              tickLine={false}
              tickMargin={10}
              axisLine={false}
              tickFormatter={(value: string) => value.slice(0, 3)}
            />
            <YAxis dataKey="bitcoin" tickLine={false} tickMargin={10} axisLine={false} />
            <Bar dataKey="bitcoin" fill="var(--color-bitcoin)" radius={4} />
            <ChartLegend content={<ChartLegendContent />} />
          </BarChart>
        </ChartContainer>
      )
    }

    Copy link

    Qodo Merge was enabled for this repository. To continue using it, please link your Git account with your Qodo account here.

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Impact
    Possible issue
    Add type safety checks

    Add type checking for the stored value to prevent runtime type errors when
    retrieving data. The current implementation allows storing any value type but
    may fail when retrieving with an incompatible type.

    src/utils/local-storage.ts [9-16]

     export function getItem<T>(key: string): T | undefined {
       try {
         const data = window.localStorage.getItem(key)
    -    return data ? (JSON.parse(data) as T) : undefined
    +    if (!data) return undefined
    +    const parsed = JSON.parse(data)
    +    if (typeof parsed !== typeof {} as T) {
    +      throw new Error(`Invalid stored type for key: ${key}`)
    +    }
    +    return parsed as T
       } catch (err) {
         console.error(err)
    +    return undefined
       }
     }
    • Apply this suggestion
    Suggestion importance[1-10]: 8

    __

    Why: The suggestion addresses a significant potential runtime issue by adding type validation, which could prevent hard-to-debug type-related errors when retrieving data from localStorage. The improved implementation provides better type safety and error handling.

    Medium
    Improve error handling for missing ID

    The error handling for missing ID parameter uses a basic Error throw which may
    crash the app. Use proper error boundaries or display a user-friendly error
    message.

    src/pages/quotes/QuotePage.tsx [92-94]

     if (!id) {
    -  throw Error("Missing `id` param.")
    +  return (
    +    <div className="p-4 text-red-500">
    +      Error: Quote ID is required
    +    </div>
    +  )
     }
    • Apply this suggestion
    Suggestion importance[1-10]: 6

    __

    Why: The suggestion improves user experience by replacing a thrown error with a user-friendly error message, preventing potential app crashes and providing better feedback.

    Low
    General
    Replace hardcoded data with API data

    The chart data is hardcoded with static values. This should be fetched from an
    API or passed as props to make the component reusable and display real data.

    src/pages/balances/BalancesPage.tsx [31-44]

    -const data = [
    -  { month: "January", bitcoin: 186 },
    -  { month: "February", bitcoin: 305 },
    -  { month: "March", bitcoin: 237 },
    -  { month: "April", bitcoin: 73 },
    -  { month: "May", bitcoin: 209 },
    -  { month: "June", bitcoin: 214 },
    -  { month: "July", bitcoin: 21 },
    -  { month: "August", bitcoin: 32 },
    -  { month: "September", bitcoin: 0 },
    -  { month: "October", bitcoin: 0 },
    -  { month: "November", bitcoin: 0 },
    -  { month: "December", bitcoin: 0 },
    -]
    +const { data: chartData } = useSuspenseQuery({
    +  queryKey: ['bitcoin-chart'],
    +  queryFn: fetchBitcoinChartData
    +})
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion addresses an important maintainability issue by proposing to replace static mock data with real API data, which would make the chart component more dynamic and production-ready.

    Medium
    Add error state handling

    Add error simulation to the mock handler to test error handling in the client
    code. The current implementation only returns successful responses.

    src/mocks/handlers/balances.ts [6-13]

     export const fetchBalances = http.get<never, never, BalancesResponse>(`${API_URL}${BALANCES}`, async () => {
       await delay(1_000)
    +  if (Math.random() < 0.1) { // 10% chance of error
    +    return new HttpResponse(null, {
    +      status: 500,
    +      statusText: 'Internal Server Error'
    +    })
    +  }
       return HttpResponse.json({
         bitcoin: {
           value: "42.12345678",
           currency: "BTC",
         },
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    __

    Why: The suggestion improves the mock handler's robustness by simulating error scenarios, which is crucial for testing error handling in the client code. This enhancement helps ensure the application handles API failures gracefully.

    Medium
    • More

    @mjkeaton mjkeaton merged commit 6aadf75 into master Feb 25, 2025
    3 checks passed
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    enhancement New feature or request Review effort 4/5
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    1 participant